use std::env::args;
use std::str::StrExt;
use std::path::Path;
use std::fs;
use std::fs::PathExt;
use std::process::Command;
use std::process::ExitStatus;
use std::iter::IteratorExt;

// cmmand line:  rustc [rust-flags] [[srcfile.rs] [args-for-execute]]
fn main() {
    let args: Vec<_> = args().collect();
    assert!(args.len() >= 1);

    let (rustc_args, source_file, progr_args) = match args.iter().position(|x| x.ends_with(".rs")) {
        Some(1) if args.len() == 2              => (None, Some(&args[1]), None),
        Some(1)                                 => (None, Some(&args[1]), Some(&args[2..])),
        Some(index) if args.len()-1 == index    => (Some(&args[1..index]), Some(&args[index]), None),
        Some(index)                             => (Some(&args[1..index]), Some(&args[index]), Some(&args[index+1..])),
        None if args.len() == 1                 => (None, None, None),
        None                                    =>(Some(&args[1..]), None, None)
    };

    //println!("rustc args : {:?}", rustc_args);
    //println!("source file: {:?}", source_file);
    //println!("progr args : {:?}", progr_args);

    let out_name = source_file.map(|x| &x[..(x.len()-3)]);
    //println!("out file: {:?}", out_name);

    let mut cmd = Command::new("rustc");
    if let Some(a) = rustc_args { cmd.args(a); }
    if let Some(o) = out_name { cmd.arg("-o").arg(o); }
    if let Some(f) = source_file { cmd.arg(f); }

    // command
    match cmd.status() {
        Ok(status) if status.success() => {}
        _ => return
    }


    if let Some(name) = out_name {
        let name = if name.contains('/') { name.to_string() } else { format!("./{}", name) };
        let path = Path::new(&name[..]);

        if !path.exists() { println!("no exucutable file [{}] exists.", name); return; }

        let separator = format!("------------------------{}------------------------", path.display());
        println!("{}", separator);
        cmd = Command::new(&name);
        if let Some(a) = progr_args { cmd.args(a); }
        cmd.status();
        println!("{}", separator.chars().map(|x| if x != '-' { '-' } else { x }).collect::<String>());

        // clean up
        if path.exists() { fs::remove_file(&path); }
    };
}
